package com.yhx.security.icbcGuomi;


import java.io.IOException;
import java.math.BigInteger;
import java.util.Arrays;


import org.bouncycastle.asn1.*;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;


public class RSToAns1 {




    /*
     * 解析SM2签名， 将ANS1 格式转换为R||S
     * return string字符串，第一个为返回码，第二个为转换后的r||s
     */
    public  static String[] reformatRS(String  dataHex){

        byte[] data = Hex.decode(dataHex);
        String[] ret = new String[2];
        if(data == null){
            ret[0] = "9997";
            return ret;
        }

        byte[] rs = null;
        try {
            rs = reformatRS(data);
        } catch (Exception e) {
            ret[0] = "9997";
            return ret;
        }

        ret[0] = "0000";
        ret[1] =new String(Hex.decode(rs));
        return ret;
    }



    /*
     * 解析SM2签名， 将ANS1 格式转换为R||S
     * return string字符串，第一个为返回码，第二个为转换后的r||s
     */
    public  static byte[] reformatRS(byte[]  data) throws Exception ,IOException{

        String data_rs = null;

        ASN1Sequence seq = null;
        //seq = (ASN1Sequence) ASN1Primitive.fromByteArray(data);

        if (seq.size() == 2)
        {
            byte[] r = ((ASN1Integer)seq.getObjectAt(0)).getValue().toByteArray();
            if(r.length < 32){   // 随机生成时r的高位为X'00'
                throw new Exception("signature r is less than 32 byte: " + r);
            }
            byte[] s = ((ASN1Integer)seq.getObjectAt(1)).getValue().toByteArray();
            if(s.length < 32){   // 根据r计算得到的s的高位为X'00'
                throw new Exception("signature s is less than 32 byte: " + s);
            }

            String rstr = new String(Hex.decode(r));
            if(rstr.length() == 66 && rstr.substring(0, 2).equalsIgnoreCase("00")){
                rstr = rstr.substring(2, rstr.length());
            }

            String sstr =  new String(Hex.decode(s));
            if(sstr.length() == 66 && sstr.substring(0, 2).equalsIgnoreCase("00")){
                sstr = sstr.substring(2, sstr.length());
            }

            data_rs = rstr + sstr;

        }

        return Hex.decode(data_rs);
    }

    /**
     *  将R||S，转换为符合ASN1规范的编码
     *  @param dataBase base编码的rsdata
     *  @return ans1编码 数据，hex字符串。
     *
     */

    public static String  reformatASN1(String dataBase) throws Exception{
        byte[] data = Base64.decode(dataBase);
        byte[] derdata = reformatASN1(data);
        return new String(Hex.decode(derdata));

    }


    /*
     *  将R||S，转换为符合ASN1规范的编码
     *
     */

    public static byte[]  reformatASN1(byte[] data) throws Exception{
        if(data.length < 64){
            throw new Exception("signature is not 64 byte: " + data);
        }
        System.setProperty("com.icbc.bcprov.org.bouncycastle.asn1.allow_unsafe_integer", "true");
        byte[] derData = null;
        try {

            byte[] r = Arrays.copyOfRange(data, 0, 32);
            byte[] s = Arrays.copyOfRange(data, 32, 64);

            ASN1EncodableVector v = new ASN1EncodableVector();
            v.add(new ASN1Integer(new BigInteger(1, r)));
            v.add(new ASN1Integer(new BigInteger(1, s)));
            derData = new DERSequence(v).getEncoded(ASN1Encoding.DER);

        }catch (IOException e) {
            e.printStackTrace();
            System.setProperty("com.icbc.bcprov.org.bouncycastle.asn1.allow_unsafe_integer", "false");
            return null;
        }
        System.setProperty("com.icbc.bcprov.org.bouncycastle.asn1.allow_unsafe_integer", "false");
        return derData;
    }

}
